שפת C/ביטויים בוליאניים ותנאים
כדי להשתמש בנתונים שנקלטו מהמשתמש ולנתב בעזרתם את התוכנה, מדי פעם צריכים לעשות בדיקה של הנתונים. ערכים בוליאניים אמת ושקר, וייצוגם בשפת C ביטוי בוליאני הוא ביטוי שיכול לקבל את הערכים "אמת" ו"שקר". לעתים צריך בתכניות מחשב להכריע האם דבר הוא אמת או שקר, לדוגמה, האם נכון שערכו של המשתנה x הוא 6, או האם שקר הוא שערכו של המשתנה x קטן מערכו של המשתנה y. בשפת C נהוגה המוסכמה שהערך המספרי 0 מציין "שקר", וכל ערך אחר מציין "אמת". בהמשך דף זה ובלולאות נראה כיצד לגרום למחשב לבצע פעולות שונות בהתאם לשאלה האם ערך כלשהו הוא אמת או שקר. אופרטורים בוליאניים שפת C כוללת מספר אופרטורים בוליאניים, כלומר אופרטורים שתוצאתם היא "אמת" או "שקר". לדוגמה, כדי לבדוק האם ערך המשתנה x הוא 6, רושמים x 6 כאשר יתבצע קטע קוד זה, יתרגם אותו המחשב ל"אמת" (ערך כלשהו שאינו 0) אם ערך x אכן 6, או ל"שקר" (הערך המספרי 0) אם ערכו שונה. שים לב להבדל בין האופרטור לבין פעולת ההשמה =. לשפת C האופרטורים הבוליאניים הבאים: * (להבדיל מ= המשמש להשמה) - האם שני צדי הביטוי שווים *=! - האם שני צדי הביטוי שונים *> - האם הצד הימני של הביטוי גדול מצדו השמאלי *< - האם הצד הימני של הביטוי קטן מצדו השמאלי *=> - האם הצד הימני של הביטוי גדול או שווה לצדו השמאלי *=< - האם הצד הימני של הביטוי קטן או שווה לצדו השמאלי תוכל לראות כיצד משתמשים באופרטורים בוליאניים בהתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא). אופרטורים לוגיים גימום, איווי, ושלילה ביטוי בוליאני יכול להיות מורכב גם מאוסף של ביטויים בוליאניים פשוטים יותר, המחוברים על ידי קשרים לוגיים, למשל: "אם x שווה 5 או x שווה 6", או: "אם x גדול מ-y וגם y גדול מ-z", וכדומה. גימום (conjunction בלעז), כלומר הקשר הלוגי "וגם", מיוצג על ידי שני התווים &&: && כאשר condition_1 וcondition_2 הם שני תנאים בוליאניים, והגימום הוא אמת אם ורק אם שניהם אמת. לדוגמה: x 5 && y 6 הוא התנאי שערכו של x הוא 5 וכן ערכו של y הוא 6. איווי (disjunction בלעז), כלומר הקשר הלוגי "או", מיוצג על ידי שני התווים ||: || כאשר condition_1 וcondition_2 הם שני תנאים בוליאניים, והאיווי הוא אמת אם ורק אם לפחות אחד מהם אמת אמת. לדוגמה: x 5 || y 6 הוא התנאי שערכו של x הוא 5 או שערכו של y הוא 6. שלילה (negation בלעז), כלומר הקשר הלוגי "לא", מיוצג על ידי התו !: ! כאשר condition הוא תנאי בוליאני, והשלילה היא אמת אם ורק אם התנאי הוא שקר. לדוגמה: !(x 5) הוא התנאי השולל שערכו של x הוא 5. ניתן גם ליצור תנאים המורכבים ממספר גדול יותר של ביטויים וקשרים לוגיים, ולהשתמש בסוגריים ע"מ לקבוע את סדר חישובם. למשל: a > b || (a <= b && b 5) תוכל לראות כיצד משתמשים באופרטורים בוליאניים בהתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא). הערכת ביטויים לוגיים מורכבים בעת הרצת התוכנית מתבצע חישוב של תנאי מורכב משמאל לימין, ובשימוש בקצר לוגי (שיוסבר להלן). נתבונן בתנאי המורכב: x 5 || y 6 מבין שני הביטויים כאן, הביטוי השמאלי, x 5 הוא זה שיוערך ראשון. כעת יש שתי אפשרויות: *אם ביטוי זה הוא שקר, עדיין יכול הביטוי המורכב, x 5 || y 6, להיות אמת - יש לבדוק אם הביטוי הימני, y 6, הוא אמת. * אם ביטוי זה הוא אמת, אז הביטוי המורכב, x 5 || y 6, בהכרח אמת. אין צורך אפילו לבדוק את הביטוי הימני. השפה מבטיחה במקרה זה לערוך קצר לוגי - היא כלל לא תעריך את y 6. השפה מבטיחה שני סוגי קצרים לוגיים. בתנאי המורכב || לא יוערך הביטוי right_condition אם left_condition אמת. בתנאי המורכב && לא יוערך הביטוי right_condition אם left_condition שקר. בשפת C, הידועה בקצרנותה, מתכנתים משתמשים בקצרים לוגיים באופן תדיר. לדוגמה: if(x != 0 && 1 / x < 2) printf("OK"); מבטיחה, על ידי קצר לוגי, שלא תתבצע בטעות חלוקה ב0. תנאי בקרה תנאי בקרה (selection statements) מאפשרים לציין אלה קטעי קוד יבוצעו בהתאם לתנאים כלשהם. if משפטי תנאי מתחילים במילה if, לאחריו ביטוי בוליאני, ולאחריו הפקודה (או הבלוק) שיש לבצע במקרה שהביטוי הבוליאני אמת: if() כאשר condition הוא התנאי הבוליאני לבדיקה, וaction הוא הפקודה (או הבלוק). התרשים הבא מראה את התנאי בצורה גרפית: מרכז|100%|התנאי if לדוגמה, קטע הקוד: if(x 6) printf("x is 6"); ידפיס אם ערך x אכן 6 תתבצע ההדפסה (ואם לא - לא). כמובן שנוכל ליצור תנאים מסובכים מעט יותר: * אפשר להשתמש באופרטורים בוליאניים ולוגיים כדי ליצור תנאים בוליאניים מורכבים לבדיקת הif * אפשר להשתמש בבלוקים כדי לבצע רצף של פקודות במקרה שהתנאי אמת else לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים. במקרה זה אפשר להשתמש בתנאי if / else. if() else כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, וalternative_action הוא פקודה (או בלוק) לביצוע אם אינו מתקיים. התרשים הבא מראה את התנאי בצורה גרפית: מרכז|100%|התנאי if-else לדוגמה: if(x 6) y += 2; else y = 8; יחבר 2 לy אם x 6, ויקבע את ערכו של y ל8 אם ערכו של x אינו 6. else if לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים, אך תנאי אחר כן מתקיים. במקרה זה אפשר להשתמש בתנאי if / else if. if() else if() כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, alternative_condition הוא תנאי לבדיקה אם condition הוא שקר, וalternative_action הוא פקודה (או בלוק) לביצוע אם condition הוא שקר אך alternative_condition הוא אמת. לדוגמה: if(x 6) y += 2; else if(x % 2 0) y = 8; יחבר 2 לy אם x 6, ויקבע את ערכו של y ל8 אם ערכו של x אינו 6 אך x זוגי. שילובי if / else if / else ניתן לשלב בין שלושת תנאי הבקרה שראינו. המבנה הכללי ביותר הוא: # תנאי if, שלאחריו # אפס או יותר תנאי if else, שלאחר האחרון שבהם (אם יש כאלה) # תנאי else אופרטור התניה אופרטור התניה מאפשר לציין ערך שתלוי בתנאי כלשהו. אופן כתיבתו הוא בצורה: ? : כאשר condition הוא ביטוי בוליאני, true_value הוא הערך אם condition תקף, וfalse_value הוא הערך אחרת. לדוגמה a 3? 1 : 2 הוא בעל הערך 1 אם a אכן שווה ל3, והוא בעל הערך 2 אחרת. חשוב להבין שאפשר להשתמש באופרטור התניה כערך לכל דבר. לדוגמה, ניתן לכתוב: int b = a 3? 1 : 2; וכן prinf("%s is the winner", a > 5? "moshe" : "yaakov"); switch-case switch-case הוא סוג נוסף של משפט בקרה. המבנה שלו הוא מהצורה: switch() { case : break; case : break; ... default: } כאשר: * expression הוא ערך (לרוב נתון כערכו של משתנה) * value_0, value_1, ..., הם ערכים קבועים. * action_0, action_1, ..., הם פקודות או רצפי פקודות. * default_action הוא פקודה או רצף פקודה. כאשר רצף התכנית מגיע לפקודת switch, מתבצעים השלבים הבאים: # הערך expression מחושב # נבדק מי הוא הערך הראשון מבין הערכים value_0, value_1,... שערכו זהה לexpression. הפקודה המתאימה לערך הראשון הנ"ל תבוצע. # אם אף ערך מתאים לexpression, ותנאי ברירת המחדל (default) נמצא, אז הפקודה המתאימה לו תבוצע. התכנית הבאה מדגימה את השימוש בswitch: #include int main() { char rep; printf("Click a number between 1 and 4"); rep = getchar(); switch(rep) { case '1': printf("You clicked 1, have a good day"); break; case '2': printf("You clicked 2, have a nice day"); break; case '3': printf("You clicked 3, have a happy day"); break; case '4': printf("You clicked 4, have a great day"); break; default: printf("You did not click a number between 1 and 4"); return -1; } return 0; } ביטויים בוליאניים ותנאים